import { View, Image, Input, Picker, Text, Button } from "@tarojs/components";
import "./index.less";
import { defineComponent, ref, computed } from "vue";
import { getImageURL, isPointInRectangle, PromiseWith, Login } from "@/utils";
import Taro from "@tarojs/taro";
import {
  get_active_info,
  get_user_phone,
  login_user_info,
  post_user_reserve,
  post_user_writeOff,
} from "@/services";

export default defineComponent({
  setup() {
    const step = ref("preload");
    const windowInfo = Taro.getWindowInfo();
    const { screenWidth, windowWidth, windowHeight } = windowInfo;
    const percentage = screenWidth / 750;
    const hasTip = ref(true);
    const formData = ref({});
    const preloadPercentage = ref(0);
    const preloadList = ref([]);
    const scenesSource = ref([]);
    const showRule = ref(false);
    let preloadLength = 0;
    // 禁用的场次信息
    const disabledSceneMap = new Map();
    const resourceMap = {
      step1: getImageURL("/step-1.jpg"),
      step2: getImageURL("/step-2.jpg"),
      step3: getImageURL("/step-3.jpg"),
      step4: getImageURL("/step-4.jpg"),
      mouse: getImageURL("/mouse.png"),
      confirm: getImageURL("/confirm.png"),
      tip: getImageURL("/tip.png"),
      btnYiruchang: getImageURL("/btn-yiruchang.png"),
      btnHexiaoPng: getImageURL("/btn-hexiao.png"),
      btnChongxin: getImageURL("/btn-chongxin.png"),
      btnRule: getImageURL("/btn-rule.png"),
      bg: getImageURL("/bg.jpg"),
      btn: getImageURL('/btn.png'),
      rule: getImageURL('/rule.png'),
      txt1: getImageURL('/txt-1.png'),
      txt2: getImageURL('/txt-2.png')
    }

    const startPreload = () => {
      const list = [
        resourceMap.step1,
        resourceMap.step2,
        resourceMap.step3,
        resourceMap.step4,
        resourceMap.mouse,
        resourceMap.confirm,
        resourceMap.tip,
        resourceMap.btnYiruchang,
        resourceMap.btnHexiaoPng,
        resourceMap.btnChongxin,
        resourceMap.bg,
        resourceMap.btn,
        resourceMap.rule,
      ]
      const cites = projectInfo.value.cites || [];
      list.push(...cites.map((t) => t.url));
      list.push(projectInfo.value.bg);
      preloadList.value = list;
    };
    const onPreload = (e) => {
      preloadLength++;
      const count = preloadList.value.length;
      preloadPercentage.value = Math.floor((preloadLength / count) * 100);
      if (preloadLength === count) {
        if (formData.value.user_phone) {
          step.value = "over";
        } else {
          step.value = "init";
        }
      }
    };
    // 设计图转真实像素
    const transformToSketchpad = (v) => {
      return v * percentage;
    };
    // 项目基本信息
    const projectInfo = ref({});
    const currentProject = ref();
    // 地点列表
    const cites = computed(() => {
      return projectInfo.value.cites;
    });
    // 日期列表
    const dates = computed(() => {
      const list = projectInfo.value.cites || [];
      const city_id = formData.value.city_id;
      const find = list.find((t) => t.city_id === city_id);
      if (find) return find.dates || [];
      return [];
    });
    // 场次列表
    const scenes = computed(() => {
      const { city_id, date } = formData.value;
      if (!city_id) return [];
      if (!date) return [];

      return scenesSource.value.filter(({ scene_id }) => {
        return !disabledSceneMap.has(`${city_id}_${date}_${scene_id}`);
      });
    });

    Taro.useLoad(async (options) => {
      try {
        const code = await Login();
        const channel = options.scene
        const userinfo = await login_user_info(code, channel);
        formData.value = userinfo;
        const data = await get_active_info();
        const { cites, scenes, disabled, ...rest } = data;
        scenesSource.value = scenes;
        disabled.forEach(({ city_id, date, scene_id }) => {
          disabledSceneMap.set(`${city_id}_${date}_${scene_id}`, true);
        });

        projectInfo.value = {
          ...rest,
          cites: cites.map(({ x, y, width, height, ...rest }) => {
            return {
              x: transformToSketchpad(x),
              y: transformToSketchpad(y),
              width: transformToSketchpad(width),
              height: transformToSketchpad(height),
              ...rest,
            };
          }),
        };
        startPreload();
      } catch (ex) {
        Taro.showToast({
          title: ex.message,
          icon: "none",
          duration: 1000 * 60,
          mask: true,
        });
      }

      console.log("onLoad projectInfo", projectInfo.value);
    });
    Taro.useDidShow((options) => {
      console.log("show", options);
    });
    const isEmpty = (v) => {
      if (v === null || v === undefined || v === "") return true;
      if (typeof v === "string" && v.trim() === "") return true;
      return false;
    };
    const onSubmit = () => {
      let message;
      if (isEmpty(formData.value.user_name)) message = "请输入姓名";
      else if (isEmpty(formData.value.city_id)) message = "请选择城市";
      else if (isEmpty(formData.value.date)) message = "请选择日期";
      else if (isEmpty(formData.value.scene_id)) message = "请选择场次";
      else if (isEmpty(formData.value.user_phone)) message = "请获取手机号";

      if (message) {
        Taro.showToast({
          title: message,
          icon: "none",
        });
        return;
      }
      Taro.showLoading({ mask: true });
      post_user_reserve(formData.value)
        .then((res) => {
          Taro.hideLoading();
          step.value = "over";
          formData.value = res;
        })
        .catch((ex) => {
          Taro.hideLoading();
          Taro.showToast({
            title: ex.message,
            mask: true,
          });
        });
    };

    const onWriteOffSubmit = () => {
      Taro.showLoading({ mask: true });
      post_user_writeOff(formData.value.openid)
        .then((res) => {
          formData.value = res;
          formData.value.showWriteOffConfirm = false;
          Taro.hideLoading();
        })
        .catch((ex) => {
          Taro.hideLoading();
          Taro.showToast({
            title: ex.message,
            mask: true,
          });
        });
    };

    const mousePoint = ref({
      x: transformToSketchpad(296),
      y: transformToSketchpad(790),
      width: transformToSketchpad(188 / 2),
      height: transformToSketchpad(125 / 4),
    });
    const mouseDownOffset = { x: 0, y: 0, drag: false };
    const onTouchStart = (e) => {
      const { type } = e.target.dataset;
      // if (type !== "mouse") return;
      if (hasTip.value) hasTip.value = false;
      const [ { pageX, pageY } ] = e.touches;
      mouseDownOffset.x = pageX - mousePoint.value.x;
      mouseDownOffset.y = pageY - mousePoint.value.y;
      mouseDownOffset.drag = true;
    };
    const onTouchMove = (e) => {
      if (!mouseDownOffset.drag) return;
      const { touches } = e;
      const [ { pageX, pageY } ] = touches;
      mousePoint.value.x = Math.min(
        Math.max(pageX - mouseDownOffset.x, -mousePoint.value.width),
        windowWidth - mousePoint.value.width
      );
      mousePoint.value.y = Math.min(
        Math.max(pageY - mouseDownOffset.y, -mousePoint.value.height),
        windowHeight - mousePoint.value.height
      );

      const cites = projectInfo.value?.cites || [];
      currentProject.value = null;
      for (const item of cites) {
        if (
          isPointInRectangle(
            {
              x: mousePoint.value.x + mousePoint.value.width,
              y: mousePoint.value.y + mousePoint.value.height,
            },
            item
          )
        ) {
          currentProject.value = item;
          formData.value.city_id = item.city_id;
          formData.value.city_name = item.city_name;
          break;
        }
      }
    };
    const onTouchEnd = () => {
      mouseDownOffset.drag = false;
    };

    const renderStepDraw = () => {
      return (
        <View
          key="draw"
          class="city-container step-draw"
          onTouchmove={onTouchMove}
          onTouchend={onTouchEnd}
          onTouchcancel={onTouchEnd}
          onTouchstart={onTouchStart}
        >

          <Image class="pos bg" src={projectInfo.value.bg}/>
          <Image class="pos btn-rule" src={resourceMap.btnRule}/>
          {hasTip.value && <View class="pos bg bg-mask"/>}
          <Image
            data-type="mouse"
            class="pos mouse"
            style={`top:${mousePoint.value.y}px;left:${mousePoint.value.x}px`}
            src={resourceMap.mouse}
          />
          {hasTip.value && (
            <Image src={resourceMap.tip} class="pos tip"/>
          )}

          {projectInfo.value?.cites?.map(({ city_id, url }) => {
            return (
              <Image
                key={`active_city_${city_id}`}
                class={`pos bg city ${
                  city_id === currentProject.value?.city_id ? "active" : ""
                }`}
                src={url}
              />
            );
          })}
          {currentProject.value && <Image
            src={resourceMap.btn}
            class={`pos btn ${currentProject.value ? "active" : ""}`}
            onTap={() => {
              if (!currentProject.value) return;
              step.value = "getUserInfo";
            }}
          />}

          {renderRule()}
        </View>
      );
    };

    const renderStepInit = () => {
      return (
        <View key="init" class="city-container">
          <Image class="pos bg" src={resourceMap.step2}/>
          <View
            class="placeholder btn-yuyue"
            onTap={() => {
              hasTip.value = true;
              step.value = "draw";
            }}
          />
          <Image class="footer-text" src={resourceMap.txt1}/>
        </View>
      );
    };
    const onGetphonenumber = (userInfoRes) => {
      const { encryptedData, iv, code } = userInfoRes.detail;
      get_user_phone(code)
        .then((data) => {
          formData.value.user_phone = data.purePhoneNumber;
        })
        .catch((ex) => {
          Taro.showToast({
            title: ex.message,
            icon: "none",
          });
        });
      console.log(encryptedData, iv, code);
    };
    const renderGetUserInfo = () => {
      return (
        <View key="step-userinfo" class="city-container step-get-userinfo">
          <Image class="pos bg" src={resourceMap.step3}/>
          <View class="form">
            <Input
              class="placeholder ipt-username"
              value={formData.value.user_name}
              placeholder="姓名"
              maxlength={20}
              onInput={(e) => {
                formData.value.user_name = e.detail.value;
              }}
            />
            <View class="placeholder ipt-phone">
              {formData.value.user_phone}
            </View>
            <Button
              class="placeholder ipt-phone-get"
              open-type="getPhoneNumber"
              onGetphonenumber={onGetphonenumber}
            />
            <Picker
              class="placeholder ipt-city-picker"
              label="地点"
              range={cites.value}
              onChange={(e) => {
                formData.value.date = null;
                formData.value.date_name = null;
                formData.value.scene_id = null;
                formData.value.scene_name = null;
                const city = projectInfo.value.cites[Number(e.detail.value)];
                formData.value.city_id = city.city_id;
                formData.value.city_name = city.city_name;
              }}
              range-key="city_name"
            >
              <View class="picker-content">
                {formData.value.city_name ?? "请选择"}
              </View>
            </Picker>
            <Picker
              label="日期"
              class="placeholder ipt-date-picker"
              range={dates.value}
              onChange={(e) => {
                formData.value.scene_id = null;
                formData.value.scene_name = null;
                const find = dates.value[Number(e.detail.value)];
                if (!find) return;
                formData.value.date = find.value;
                formData.value.date_name = find.name;
              }}
              range-key="value"
            >
              <View class="picker-content">
                {formData.value.date_name ?? "请选择"}
              </View>
            </Picker>
            <Picker
              label="场次"
              class="placeholder ipt-scene-picker"
              range={scenes.value}
              onChange={(e) => {
                const city = scenes.value[Number(e.detail.value)];
                if (!city) return;
                formData.value.scene_id = city.scene_id;
                formData.value.scene_name = city.scene_name;
              }}
              range-key="scene_name"
            >
              <View class="picker-content">
                {formData.value.scene_name ?? "请选择"}
              </View>
            </Picker>
            <View class="placeholder btn-submit-yuyue" onTap={onSubmit}/>
          </View>
          {renderRule()}
        </View>
      );
    };
    const renderProjectOver = () => {
      return (
        <View key="step-over" class="city-container step-over">
          <Image class="pos bg" src={resourceMap.step4}/>
          <View class="info-box">
            <Text>尊敬的{formData.value.user_name}，您已成功预约</Text>
            <Text>{`请于${new Date().getFullYear()}年${
              formData.value.date_name
            }${formData.value.scene_name}\n`}</Text>
            <View>{`前往${formData.value.city_name}参与活动`}</View>
            <View class="one-mini-box">开启探蜜养蜂之旅<Text class="one-mini">1</Text>！</View>

            <Text class="mgt-info">
              {`您将收到来自【法国娇兰】的邀请短信\n作为入场凭证，期待您的莅临！`}

            </Text>

          </View>
          <View class="btns-box">
            {formData.value.hasWriteOff ? (
              <Image src={resourceMap.btnYiruchang} class=" btn "/>
            ) : (
              <>
                <Image
                  src={resourceMap.btnHexiaoPng}
                  class=" btn "
                  onTap={() => {
                    formData.value.showWriteOffConfirm = true;
                  }}
                />
                <Image
                  src={resourceMap.btnChongxin}
                  class=" btn "
                  onTap={() => {
                    step.value = "init";
                    formData.value.city_id = null;
                    formData.value.city_name = null;
                    formData.value.date = null;
                    formData.value.date_name = null;
                    formData.value.scene_id = null;
                    formData.value.scene_name = null;
                  }}
                />
              </>
            )}
          </View>
          {formData.value.showWriteOffConfirm && (
            <View class="confirm_mask">
              <View class="confirm-box">
                <Image src={resourceMap.confirm} class="confirm"/>
                <View
                  class="placeholder btn-cancel"
                  onTap={() => {
                    formData.value.showWriteOffConfirm = false;
                  }}
                />
                <View class="placeholder btn-submit" onTap={onWriteOffSubmit}/>
              </View>
            </View>
          )}
          {renderRule()}
          {renderFooterText()}
        </View>
      );
    };
    const renderRule = () => {
      return (
        <>
          <View
            class="placeholder rule-btn-show"
            onTap={() => (showRule.value = true)}
          />
          {showRule.value && (
            <View class="rule-box">
              <Image src={resourceMap.rule} class="pos bg"/>
              <View
                class="placeholder rule-btn-close"
                onTap={() => {
                  showRule.value = false;
                }}
              />
            </View>
          )}
        </>
      );
    };

    const renderPreload = () => {
      return (
        <View key="preload" class="city-container step-preload">
          <Image class="pos bg" src={resourceMap.step1}/>
          <View class="process-bar">
            <View class="process-text">{preloadPercentage.value}%</View>
            <View class="process" style={`width:${preloadPercentage.value}%`}/>
          </View>
          <View class="preload_hide">
            {preloadList.value.map((item) => {
              return (
                <Image
                  key={`item_${item}`}
                  src={item}
                  onLoad={onPreload}
                  onError={onPreload}
                />
              );
            })}
          </View>
        </View>
      );
    };

    const renderFooterText = () => {
      return <Image class="footer-text" src={resourceMap.txt2}/>
    }
    return () => {
      let content;
      switch (step.value) {
        case "preload":
          content = renderPreload();
          break;
        case "init":
          content = renderStepInit();
          break;
        case "draw":
          content = renderStepDraw();
          break;
        case "getUserInfo":
          content = renderGetUserInfo();
          break;
        case "over":
          content = renderProjectOver();
          break;
      }
      return <View class="page-home">{content}</View>;
    };
  },
});
